}
protected void loadState() {
- XML.load_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_INPUT_FILE );
+ XML.loadState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_INPUT_FILE );
}
protected void saveState() {
- XML.dump_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_OUTPUT_FILE );
+ XML.saveState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_OUTPUT_FILE );
}
}
if (partition_name.equals(""))
throw new ParseFailedException("Expected -p<partition_name>");
- long chunksize = Library.parse_size( size ) / Settings.SECTOR_SIZE;
+ long chunksize = Library.parseSize( size ) / Settings.SECTOR_SIZE;
if ( chunksize <= 0 )
throw new CommandFailedException("Chunk size " + size + " is smaller than sector size.");
// Initialise the partition manager and look up the partition
loadState();
- Partition p = PartitionManager.it.get_partition(partition_name);
+ Partition p = PartitionManager.IT.getPartition(partition_name);
if ( p == null )
throw new CommandFailedException("Partition " + partition_name + " does not exist.");
// Check if this partition belongs to the VDM
- if (p.getIsXeno() && !force)
+ if (p.isXeno() && !force)
throw new CommandFailedException("Refusing to add partition as it is already allocated to the virtual disk manager. Use -f if you are sure.");
String output = new CommandPartitionAdd( p, chunksize ).execute();
public class ParsePartitionsList extends CommandParser {
public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
loadState();
- Iterator i = PartitionManager.it.iterator();
+ Iterator i = PartitionManager.IT.iterator();
int idx = 1;
System.out.println( " maj:min " + " blocks " + "start sect " +
" num sects " + "name" );
while (i.hasNext()) {
Partition p = (Partition) i.next();
- if (p.getIsXeno()) {
+ if (p.isXeno()) {
System.out.print("[ ");
} else {
System.out.print(" ");
}
- System.out.print(Library.format(idx++, 2, 0) + " ");
- System.out.print(Library.format(p.getMajor(),3,0) + ":" +
- Library.format(p.getMinor(),3,1) + " " +
- Library.format(p.getBlocks(),10,0) + " " +
- Library.format(p.getStartSect(),10,0) + " " +
- Library.format(p.getNumSects(),10,0) + " " +
- Library.format(p.getName(),7,1));
- if (p.getIsXeno()) {
+ System.out.print(Library.format(idx++, 2, false) + " ");
+ System.out.print(Library.format(p.getMajor(),3,false) + ":" +
+ Library.format(p.getMinor(),3,true) + " " +
+ Library.format(p.getBlocks(),10,false) + " " +
+ Library.format(p.getStartSect(),10,false) + " " +
+ Library.format(p.getNumSects(),10,false) + " " +
+ Library.format(p.getName(),7,true));
+ if (p.isXeno()) {
System.out.println("]");
} else {
System.out.println();
// Initialise the partition manager and look up the partition
loadState();
- Partition p = PartitionManager.it.get_partition(partition_name);
+ Partition p = PartitionManager.IT.getPartition(partition_name);
if ( p == null )
throw new CommandFailedException("Partition " + partition_name + " does not exist.");
// Check if this partition belongs to the VDM
- if (p.getIsXeno() && !force)
+ if (p.isXeno() && !force)
throw new CommandFailedException("Refusing to grant physical access as the given partition is allocated to the virtual disk manager. Use -f if you are sure.");
// Convert the partition into a physical extent
Entry entry = (Entry) i.next();
Extent e = (Extent) entry.getKey();
String mode = entry.getValue().toString();
- Partition p = PartitionManager.it.get_partition( e );
+ Partition p = PartitionManager.IT.getPartition( e );
if ( p != null ) {
- System.out.println(Library.format(p.getMajor(),3,0) + ":" +
- Library.format(p.getMinor(),3,1) + " " +
- Library.format(p.getBlocks(),10,0) + " " +
- Library.format(p.getStartSect(),10,0) + " " +
- Library.format(p.getNumSects(),10,0) + " " +
- Library.format(p.getName(),7,1) + " " +
- Library.format(mode,2,1));
+ System.out.println(Library.format(p.getMajor(),3,false) + ":" +
+ Library.format(p.getMinor(),3,true) + " " +
+ Library.format(p.getBlocks(),10,false) + " " +
+ Library.format(p.getStartSect(),10,false) + " " +
+ Library.format(p.getNumSects(),10,false) + " " +
+ Library.format(p.getName(),7,true) + " " +
+ Library.format(mode,2,true));
} else {
- System.out.println(Library.format(e.getMajor(),3,0) + ":" +
- Library.format(e.getMinor(),3,1) + " " +
+ System.out.println(Library.format(e.getMajor(),3,false) + ":" +
+ Library.format(e.getMinor(),3,true) + " " +
" " + " " +
- Library.format(e.getOffset(),10,0) + " " +
- Library.format(e.getSize(),10,0) + " " +
+ Library.format(e.getOffset(),10,false) + " " +
+ Library.format(e.getSize(),10,false) + " " +
" " + " " +
- Library.format(mode,2,1));
+ Library.format(mode,2,true));
}
}
}
// Initialise the partition manager and look up the partition
loadState();
- Partition p = PartitionManager.it.get_partition(partition_name);
+ Partition p = PartitionManager.IT.getPartition(partition_name);
if ( p == null )
throw new CommandFailedException("Partition " + partition_name + " does not exist.");
else
expiry = new Date(Date.parse(expiry_s));
- long size = Library.parse_size(size_s);
+ long size = Library.parseSize(size_s);
loadState();
String output = new CommandVdCreate(name,size/Settings.SECTOR_SIZE,expiry).execute();
throw new ParseFailedException("Expected -k<key>");
loadState();
- if ( VirtualDiskManager.it.get_virtual_disk_key(vd_key) == null )
+ if ( VirtualDiskManager.IT.getVirtualDisk(vd_key) == null )
throw new CommandFailedException("Virtual disk " + vd_key + " does not exist");
String output = new CommandVdDelete(vd_key).execute();
boolean verbose = getFlagParameter(args, 'v');
loadState();
- VirtualDisk free = VirtualDiskManager.it.getFreeVirtualDisk();
+ VirtualDisk free = VirtualDiskManager.IT.getFreeDisk();
System.out.println( "Free disk has " + free.getExtentCount() + " extents totalling "
- + Library.format_size(free.getSize()*Settings.SECTOR_SIZE,8,1) );
+ + Library.formatSize(free.getSize()*Settings.SECTOR_SIZE,8,true) );
if ( verbose ) {
- Iterator i = free.iterator();
+ Iterator i = free.extents();
System.out.println(" disk offset size");
while (i.hasNext()) {
Extent e = (Extent) i.next();
- System.out.println( Library.format(e.getDisk(), 6, 0) + " "
- + Library.format(e.getOffset(), 12, 0) + " "
- + Library.format(e.getSize(), 12, 0) );
+ System.out.println( Library.format(e.getDisk(), 6, false) + " "
+ + Library.format(e.getOffset(), 12, false) + " "
+ + Library.format(e.getSize(), 12, false) );
}
}
}
public class ParseVdShow extends CommandParser {
public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
- int vd_num = getIntParameter(args,'n',-1);
+ String key = getStringParameter(args,'k',"");
loadState();
- if ( vd_num < 0 ) {
- System.out.println("num key expiry name size");
- for (int i=0;i<VirtualDiskManager.it.getVirtualDiskCount();i++) {
- VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(i);
- System.out.print( Library.format(i,3,0) + " " + vd.getKey() + " " );
+ if ( key.equals("") ) {
+ System.out.println("key expiry name size");
+ Iterator i = VirtualDiskManager.IT.getVirtualDisks();
+ while ( i.hasNext() ) {
+ VirtualDisk vd = (VirtualDisk) i.next();
+ System.out.print( vd.getKey() + " " );
if ( vd.getExpiry() != null )
System.out.print( vd.getExpiry().toString() );
else
System.out.print( " " );
- System.out.println( " " + Library.format(vd.getName(),16,1) + " "
- + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,0) );
+ System.out.println( " " + Library.format(vd.getName(),16,true) + " "
+ + Library.formatSize(vd.getSize()*Settings.SECTOR_SIZE,8,false) );
}
} else {
- VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(vd_num);
+ VirtualDisk vd = VirtualDiskManager.IT.getVirtualDisk(key);
if ( vd == null )
- throw new CommandFailedException("There is no virtual disk " + vd_num );
+ throw new CommandFailedException("There is no virtual disk " + key );
System.out.println(" name: " + vd.getName());
System.out.println(" key: " + vd.getKey());
- System.out.println(" size: " + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,1));
+ System.out.println(" size: " + Library.formatSize(vd.getSize()*Settings.SECTOR_SIZE,8,true));
if ( vd.getExpiry() != null )
System.out.println("expiry: " + vd.getExpiry());
System.out.println();
- Iterator i = vd.iterator();
+ Iterator i = vd.extents();
System.out.println(" disk offset size");
while (i.hasNext()) {
Extent e = (Extent) i.next();
- System.out.println( Library.format(e.getDisk(), 6, 0) + " "
- + Library.format(e.getOffset(), 12, 0) + " "
- + Library.format(e.getSize(), 12, 0) );
+ System.out.println( Library.format(e.getDisk(), 6, false) + " "
+ + Library.format(e.getOffset(), 12, false) + " "
+ + Library.format(e.getSize(), 12, false) );
}
}
}
}
public String execute() throws CommandFailedException {
- VirtualDiskManager.it.add_xeno_partition(partition,chunksize);
- PartitionManager.it.add_xeno_partition(partition);
+ VirtualDiskManager.IT.addPartition(partition,chunksize);
+ PartitionManager.IT.addXenoPartition(partition);
return "Added partition " + partition.getName();
}
}
* to modes.
*/
public class CommandPhysicalList extends Command {
- private int domain_id;
- private Defaults d;
- private Map map = new HashMap();
+ private int domain_id;
+ private Defaults d;
+ private Map map = new HashMap();
- /**
- * Constructor for CommandDomainList.
- * @param d Defaults object to use.
- */
- public CommandPhysicalList(Defaults d, int domain_id) {
- this.d = d;
- this.domain_id = domain_id;
- }
+ /**
+ * Constructor for CommandDomainList.
+ * @param d Defaults object to use.
+ */
+ public CommandPhysicalList(Defaults d, int domain_id) {
+ this.d = d;
+ this.domain_id = domain_id;
+ }
- /**
- * Retrieves the list of extents.
- * @return null, call extents() to get the list.
- */
- public String execute() throws CommandFailedException {
- Runtime r = Runtime.getRuntime();
- String outline;
- BufferedReader in;
- String output = null;
+ /**
+ * Retrieves the list of extents.
+ * @return null, call extents() to get the list.
+ */
+ public String execute() throws CommandFailedException {
+ Runtime r = Runtime.getRuntime();
+ String outline;
+ BufferedReader in;
+ String output = null;
- try {
- Process start_p;
- String start_cmdarray[] = new String[2];
- int start_rc;
- start_cmdarray[0] = d.XIToolsDir + "xi_phys_probe";
- start_cmdarray[1] = Integer.toString( domain_id );
+ try {
+ Process start_p;
+ String start_cmdarray[] = new String[2];
+ int start_rc;
+ start_cmdarray[0] = d.XIToolsDir + "xi_phys_probe";
+ start_cmdarray[1] = Integer.toString(domain_id);
- if (Settings.TEST) {
- output = reportCommand(start_cmdarray);
- } else {
- start_p = r.exec(start_cmdarray);
- start_rc = start_p.waitFor();
- if (start_rc != 0) {
- throw CommandFailedException.XICommandFailed("Could not get extent list", start_cmdarray);
- }
+ if (Settings.TEST) {
+ output = reportCommand(start_cmdarray);
+ } else {
+ start_p = r.exec(start_cmdarray);
+ start_rc = start_p.waitFor();
+ if (start_rc != 0) {
+ throw CommandFailedException.XICommandFailed(
+ "Could not get extent list",
+ start_cmdarray);
+ }
- in =
- new BufferedReader(new InputStreamReader(start_p.getInputStream()));
+ in =
+ new BufferedReader(
+ new InputStreamReader(start_p.getInputStream()));
- outline = in.readLine();
- while (outline != null) {
- Extent extent = new Extent();
+ outline = in.readLine();
+ while (outline != null) {
+ int disk = -1;
+ long offset = -1;
+ long size = -1;
+
+ StringTokenizer st = new StringTokenizer(outline);
+ if (st.hasMoreTokens()) {
+ disk = Short.parseShort(st.nextToken(), 16);
+ }
+ if (st.hasMoreTokens()) {
+ offset = Long.parseLong(st.nextToken(), 16);
+ }
+ if (st.hasMoreTokens()) {
+ size = Long.parseLong(st.nextToken(), 16);
+ }
+ if (st.hasMoreTokens()) {
+ String mode = st.nextToken();
+ Extent extent = new Extent(disk,offset,size);
+ if (mode.equals("rw"))
+ map.put(extent, Mode.READ_WRITE);
+ else if (mode.equals("r"))
+ map.put(extent, Mode.READ_ONLY);
+ else
+ throw new CommandFailedException(
+ "Could not parse access mode " + mode);
+ }
- StringTokenizer st = new StringTokenizer(outline);
- if (st.hasMoreTokens()) {
- extent.disk = Short.parseShort(st.nextToken(),16);
- }
- if (st.hasMoreTokens()) {
- extent.offset = Long.parseLong(st.nextToken(),16);
- }
- if (st.hasMoreTokens()) {
- extent.size = Long.parseLong(st.nextToken(),16);
- }
- if (st.hasMoreTokens()) {
- String mode = st.nextToken();
- if ( mode.equals( "rw" ) )
- map.put( extent, Mode.READ_WRITE );
- else if ( mode.equals ( "r" ) )
- map.put( extent, Mode.READ_ONLY );
- else
- throw new CommandFailedException("Could not parse access mode " + mode);
- }
+ outline = in.readLine();
+ }
- outline = in.readLine();
+ }
+ } catch (CommandFailedException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new CommandFailedException(
+ "Could not get extent list(" + e + ")",
+ e);
}
- }
- } catch (CommandFailedException e) {
- throw e;
- } catch (Exception e) {
- throw new CommandFailedException("Could not get extent list(" + e + ")", e);
+ return output;
}
- return output;
- }
-
- public Map extents() {
- return map;
- }
+ public Map extents() {
+ return map;
+ }
}
}
public String execute() throws CommandFailedException {
- VirtualDisk vd = VirtualDiskManager.it.create_virtual_disk(name,size,expiry);
+ VirtualDisk vd = VirtualDiskManager.IT.createVirtualDisk(name,size,expiry);
if ( vd == null )
throw new CommandFailedException( "Not enough free space to create disk" );
return "Virtual Disk created with key: " + vd.getKey();
}
public String execute() throws CommandFailedException {
- VirtualDiskManager.it.delete_virtual_disk(key);
+ VirtualDiskManager.IT.deleteVirtualDisk(key);
return "Deleted virtual disk " + key;
}
}
/**
* Constructor for CommandVdRefresh.
* @param key Key to refresh.
- * @param expiry New expiry.
+ * @param expiry New expiry (null for no expiry).
*/
public CommandVdRefresh(String key, Date expiry) {
this.key = key;
}
public String execute() throws CommandFailedException {
- VirtualDiskManager.it.refresh_virtual_disk(key,expiry);
+ VirtualDisk vd = VirtualDiskManager.IT.getVirtualDisk(key);
+ if ( vd == null )
+ throw new CommandFailedException( "No such virtual disk " + key );
+ vd.refreshExpiry(expiry);
return "Refreshed virtual disk " + key;
}
}
package org.xenoserver.control;
-public class
-Extent
-{
- int disk;
- long offset; /* offset into disk */
- long size; /* size of this extent in 512 byte sectors */
-
- public int
- getDisk()
- {
- return disk;
- }
-
- public long
- getOffset()
- {
- return offset;
- }
-
- public long
- getSize()
- {
- return size;
- }
-
- public int
- getMajor()
- {
- return disk >> 8;
- }
-
- public int
- getMinor()
- {
- return disk & 0xFF;
- }
-
- public int hashCode() {
- final int PRIME = 1000003;
- int result = 0;
- result = PRIME * result + disk;
- result = PRIME * result + (int) (offset >>> 32);
- result = PRIME * result + (int) (offset & 0xFFFFFFFF);
- result = PRIME * result + (int) (size >>> 32);
- result = PRIME * result + (int) (size & 0xFFFFFFFF);
-
- return result;
- }
+/**
+ * Represents an extent on physical disk.
+ */
+public class Extent {
+ /** Disk number; 16-bit major:minor pair with no partition number. */
+ private int disk;
+ /** Offset into disk in sectors. */
+ private long offset;
+ /** Size of extent in sectors. */
+ private long size;
- public boolean equals(Object oth) {
- if (this == oth) {
- return true;
+ /**
+ * Constructor for Extent.
+ * @param disk Disk number.
+ * @param offset Offset into disk.
+ * @param size Size of extent.
+ */
+ Extent(int disk, long offset, long size) {
+ this.disk = disk;
+ this.offset = offset;
+ this.size = size;
}
- if (oth == null) {
- return false;
+ /**
+ * @return Disk number.
+ */
+ public int getDisk() {
+ return disk;
}
- if (oth.getClass() != getClass()) {
- return false;
+ /**
+ * @return Offset into disk.
+ */
+ public long getOffset() {
+ return offset;
}
- Extent other = (Extent) oth;
-
- if (this.disk != other.disk) {
- return false;
+ /**
+ * @return Size of extent.
+ */
+ public long getSize() {
+ return size;
}
- if (this.offset != other.offset) {
- return false;
+ /**
+ * @return Major number of disk.
+ */
+ public int getMajor() {
+ return disk >> 8;
}
- if (this.size != other.size) {
- return false;
+ /**
+ * @return Minor number of disk, not including partition.
+ */
+ public int getMinor() {
+ return disk & 0xFF;
}
-
- return true;
- }
-
}
import java.net.InetAddress;
import java.net.UnknownHostException;
-public class InetAddressPattern
-{
- InetAddress base;
- boolean addDom;
+/**
+ * This utility class expands configuration file patterns.
+ */
+public class InetAddressPattern {
+ /** The base InetAddress for this pattern. */
+ private InetAddress base;
+ /** If true, add the domain number to the base address. */
+ private boolean addDom;
- static InetAddressPattern parse (String t)
- {
- InetAddressPattern result = new InetAddressPattern ();
- char[] ca = t.toCharArray ();
- int len = ca.length;
+ /**
+ * Parse a pattern string into an InetAddressPattern.
+ * @param t The pattern string.
+ * @return The parsed pattern object.
+ */
+ static InetAddressPattern parse(String t) {
+ InetAddressPattern result = new InetAddressPattern();
+ char[] ca = t.toCharArray();
+ int len = ca.length;
- try {
- if (len == 0) {
- result.base = null;
- result.addDom = false;
- } else if (ca[len - 1] == '+') {
- result.base = InetAddress.getByName(t.substring(0, len - 1));
- result.addDom = true;
- } else {
- result.base = InetAddress.getByName(t);
- result.addDom = false;
- }
- } catch (UnknownHostException uhe) {
- result.base = null;
- result.addDom = false;
- }
+ try {
+ if (len == 0) {
+ result.base = null;
+ result.addDom = false;
+ } else if (ca[len - 1] == '+') {
+ result.base = InetAddress.getByName(t.substring(0, len - 1));
+ result.addDom = true;
+ } else {
+ result.base = InetAddress.getByName(t);
+ result.addDom = false;
+ }
+ } catch (UnknownHostException uhe) {
+ result.base = null;
+ result.addDom = false;
+ }
- return result;
- }
+ return result;
+ }
- public String resolve (int domain_id) {
- byte b[] = base.getAddress ();
- if (addDom) {
- if (((int)b[3]) + domain_id > 255) {
- if (((int)b[2]) + domain_id > 255) {
- if (((int)b[1]) + domain_id > 255) {
- b[0] ++;
- }
- b[1] ++;
- }
- b[2] ++;
- }
- b[3] += domain_id;
+ /**
+ * Resolve the pattern for the given domain.
+ * @param domain_id The domain ID.
+ * @return The resolved string.
+ */
+ String resolve(int domain_id) {
+ byte[] b = base.getAddress();
+ if (addDom) {
+ if (((int) b[3]) + domain_id > 255) {
+ if (((int) b[2]) + domain_id > 255) {
+ if (((int) b[1]) + domain_id > 255) {
+ b[0]++;
+ }
+ b[1]++;
+ }
+ b[2]++;
+ }
+ b[3] += domain_id;
+ }
+ return ""
+ + (b[0] + (b[0] < 0 ? 256 : 0))
+ + "."
+ + (b[1] + (b[1] < 0 ? 256 : 0))
+ + "."
+ + (b[2] + (b[2] < 0 ? 256 : 0))
+ + "."
+ + (b[3] + (b[3] < 0 ? 256 : 0));
}
- return "" +
- (b[0] + (b[0] < 0 ? 256 : 0)) + "." +
- (b[1] + (b[1] < 0 ? 256 : 0)) + "." +
- (b[2] + (b[2] < 0 ? 256 : 0)) + "." +
- (b[3] + (b[3] < 0 ? 256 : 0));
- }
- public String toString () {
- return "[" + base + (addDom ? "+dom_id" : "") + "]";
- }
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "[" + base + (addDom ? "+dom_id" : "") + "]";
+ }
}
package org.xenoserver.control;
-public class
-Library
-{
- /*
- * convert a number to a fixed width string
- */
- public static String
- format (long input, int width, int prefix)
- {
- String sss = Long.toString(input);
- String space = " ";
-
- if (width < sss.length())
- {
- width = sss.length();
- }
+/**
+ * Library functions.
+ */
+public class Library {
+ /**
+ * Convert a number to a fixed width string.
+ * @param input The number to convert.
+ * @param width The width desired.
+ * @param leftAlign True to left-align the number.
+ * @return The formatted string.
+ */
+ public static String format(long input, int width, boolean leftAlign) {
+ String sss = Long.toString(input);
+ String space = " ";
- if (prefix == 0)
- {
- return space.substring(0, width - sss.length()) + sss;
- }
- else
- {
- return sss + space.substring(0, width - sss.length());
- }
- }
-
- /*
- * convert a string to a fixed width string
- */
- public static String
- format (String input, int width, int prefix)
- {
- String space = " ";
-
- if (width < input.length())
- {
- width = input.length();
- }
+ if (width < sss.length()) {
+ width = sss.length();
+ }
- if (prefix == 0)
- {
- return space.substring(0, width - input.length()) + input;
- }
- else
- {
- return input + space.substring(0, width - input.length());
- }
- }
-
- /*
- * convert a number (string format) into
- * the corresponding integer value.
- */
- public static long
- parse_size(String size)
- {
- String substring = size;
- int suffix = 1;
- long value = 0;
-
- if (size == null)
- {
- return 0;
+ if (leftAlign) {
+ return sss + space.substring(0, width - sss.length());
+ } else {
+ return space.substring(0, width - sss.length()) + sss;
+ }
}
- if ((substring = check(size, 'm')) != null)
- {
- suffix = 1024 * 1024;
- }
- else if ((substring = check(size, 'M')) != null)
- {
- suffix = 1024 * 1024;
- }
- else if ((substring = check(size, 'k')) != null)
- {
- suffix = 1024;
- }
- else if ((substring = check(size, 'K')) != null)
- {
- suffix = 1024;
- }
- else if ((substring = check(size, 'g')) != null)
- {
- suffix = 1024 * 1024 * 1024;
- }
- else if ((substring = check(size, 'G')) != null)
- {
- suffix = 1024 * 1024 * 1024;
- }
- else
- {
- substring = size;
- }
+ /**
+ * Convert a string to a fixed-width string.
+ * @param input Input string.
+ * @param width Width desired.
+ * @param leftAlign True to left-align the string.
+ * @return The formatted string.
+ */
+ public static String format(String input, int width, boolean leftAlign) {
+ String space = " ";
- try
- {
- value = Long.decode(substring).longValue() * suffix;
- }
- catch (NumberFormatException e)
- {
- value = 0;
+ if (width < input.length()) {
+ width = input.length();
+ }
+
+ if (leftAlign) {
+ return input + space.substring(0, width - input.length());
+ } else {
+ return space.substring(0, width - input.length()) + input;
+ }
}
- return value;
- }
+ /**
+ * Parse a size which may have a k/m/g suffix into a number.
+ * @param size The size string to parse.
+ * @return The equivalent number.
+ */
+ public static long parseSize(String size) {
+ String substring = size;
+ int suffix = 1;
+ long value = 0;
- public static String
- check(String size, char suffix)
- {
- int index = size.indexOf(suffix);
+ if (size == null) {
+ return 0;
+ }
- if (index != -1)
- {
- return size.substring(0, index);
- }
- else
- {
- return null;
+ if ((substring = check(size, 'm')) != null) {
+ suffix = 1024 * 1024;
+ } else if ((substring = check(size, 'M')) != null) {
+ suffix = 1024 * 1024;
+ } else if ((substring = check(size, 'k')) != null) {
+ suffix = 1024;
+ } else if ((substring = check(size, 'K')) != null) {
+ suffix = 1024;
+ } else if ((substring = check(size, 'g')) != null) {
+ suffix = 1024 * 1024 * 1024;
+ } else if ((substring = check(size, 'G')) != null) {
+ suffix = 1024 * 1024 * 1024;
+ } else {
+ substring = size;
+ }
+
+ try {
+ value = Long.decode(substring).longValue() * suffix;
+ } catch (NumberFormatException e) {
+ value = 0;
+ }
+
+ return value;
}
- }
-
- /**
- * Formats a number of bytes in whichever way makes most sense based
- * on magnitude and width.
- *
- * @param size Number of bytes.
- * @param width Width of field - at least 5, plz.
- * @param prefix Set to 1 for left justify
- * @return The formatted string.
- */
- public static String format_size(long size,int width,int prefix) {
- char[] suffixes = { ' ', 'k', 'M', 'G' };
- int suffix = 0;
- long before = size;
- float after = 0;
-
- while ( before > 10000 ) {
- after = ((float)(before % 1024)) / 1024;
- before /= 1024;
- suffix++;
+
+ /**
+ * Check if the given size has the specified suffix.
+ * @param size Size string.
+ * @param suffix Test suffix.
+ * @return Number part of string, or null if suffix does not match.
+ */
+ private static String check(String size, char suffix) {
+ int index = size.indexOf(suffix);
+
+ if (index != -1) {
+ return size.substring(0, index);
+ } else {
+ return null;
+ }
}
-
- StringBuffer num = new StringBuffer(width);
- num.append( Long.toString( before ) );
- if ( after != 0 ) {
- int space = width - num.length() - 2;
- if ( space > 0 ) {
- num.append( '.' );
- if ( space > 3 )
- space = 3;
- num.append( Integer.toString( (int) (after * Math.pow(10,space))));
- }
+
+ /**
+ * Formats a number of bytes in whichever way makes most sense based
+ * on magnitude and width.
+ *
+ * @param size Number of bytes.
+ * @param width Width of field - at least 5, plz.
+ * @param leftAlign True for left-align.
+ * @return The formatted string.
+ */
+ public static String formatSize(long size, int width, boolean leftAlign) {
+ char[] suffixes = { ' ', 'k', 'M', 'G' };
+ int suffix = 0;
+ long before = size;
+ float after = 0;
+
+ while (before > 10000) {
+ after = ((float) (before % 1024)) / 1024;
+ before /= 1024;
+ suffix++;
+ }
+
+ StringBuffer num = new StringBuffer(width);
+ num.append(Long.toString(before));
+ if (after != 0) {
+ int space = width - num.length() - 2;
+ if (space > 0) {
+ num.append('.');
+ if (space > 3) {
+ space = 3;
+ }
+ num.append(
+ Integer.toString((int) (after * Math.pow(10, space))));
+ }
+ }
+ num.append(suffixes[suffix]);
+
+ return format(num.toString(), width, leftAlign);
}
- num.append( suffixes[suffix] );
-
- return format(num.toString(),width,prefix);
- }
}
package org.xenoserver.control;
-public class
-Mode
-{
- private final String name;
+/**
+ * Enumeration to represent an access mode.
+ */
+public class Mode {
+ /** name of this mode */
+ private final String name;
- private Mode(String name) { this.name = name; }
+ /**
+ * Construct a mode
+ * @param name Name to use.
+ */
+ private Mode(String name) {
+ this.name = name;
+ }
- public String toString() { return name; }
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return name;
+ }
- public static final Mode READ_ONLY = new Mode("ro");
- public static final Mode READ_WRITE = new Mode("rw");
+ /** Single read-only mode instance. */
+ public static final Mode READ_ONLY = new Mode("ro");
+ /** Single read-write mode instance. */
+ public static final Mode READ_WRITE = new Mode("rw");
}
-
import java.io.PrintWriter;
-public class
-Partition
-{
- int major;
- int minor;
- long blocks;
- long start_sect;
- long nr_sects;
- String name;
- boolean xeno;
-
- Partition
- duplicate ()
- {
- Partition p = new Partition();
-
- p.major = major;
- p.minor = minor;
- p.blocks = blocks;
- p.start_sect = start_sect;
- p.nr_sects = nr_sects;
- p.name = name;
- p.xeno = xeno;
-
- return p;
- }
-
- void
- dump_xml(PrintWriter out)
- {
- out.println (" <partition>\n" +
- " <major>" + major + "</major>\n" +
- " <minor>" + minor + "</minor>\n" +
- " <blocks>" + blocks + "</blocks>\n" +
- " <start_sect>" + start_sect + "</start_sect>\n" +
- " <nr_sects>" + nr_sects + "</nr_sects>\n" +
- " <name>" + name + "</name>\n" +
- " </partition>");
- }
-
- public int
- getMajor()
- {
- return major;
- }
-
- public int
- getMinor()
- {
- return minor;
- }
-
- public long
- getBlocks()
- {
- return blocks;
- }
-
- public long
- getStartSect()
- {
- return start_sect;
- }
-
- public long
- getNumSects()
- {
- return nr_sects;
- }
-
- public String
- getName()
- {
- return name;
- }
-
- public boolean
- getIsXeno()
- {
- return xeno;
- }
-
- public int hashCode() {
- final int PRIME = 1000003;
- int result = 0;
- result = PRIME * result + major;
- result = PRIME * result + minor;
- result = PRIME * result + (int) (blocks >>> 32);
- result = PRIME * result + (int) (blocks & 0xFFFFFFFF);
- result = PRIME * result + (int) (start_sect >>> 32);
- result = PRIME * result + (int) (start_sect & 0xFFFFFFFF);
- result = PRIME * result + (int) (nr_sects >>> 32);
- result = PRIME * result + (int) (nr_sects & 0xFFFFFFFF);
- if (name != null) {
- result = PRIME * result + name.hashCode();
+/**
+ * Represents a single real partition.
+ */
+public class Partition {
+ /** Major device number as seen by Linux. */
+ private int major;
+ /** Minor device number as seen by Linux. */
+ private int minor;
+ /** Number of blocks in the partition. */
+ private long blocks;
+ /** Start sector of the partition. */
+ private long start_sect;
+ /** Number of sectors in the partition. */
+ private long nr_sects;
+ /** Name of the partition. */
+ private String name;
+ /** True if this partition is a XenoPartition. */
+ private boolean xeno;
+
+ /**
+ * Mark this partition as a XenoPartition.
+ */
+ void makeXeno() {
+ xeno = true;
}
- return result;
- }
+ /**
+ * Constructor for Partition.
+ * @param major Major number
+ * @param minor Minor number
+ * @param blocks Size in blocks
+ * @param start_sect Start sector
+ * @param nr_sects Number of sectors
+ * @param name Name of partition
+ * @param xeno True if XenoPartition
+ */
+ Partition(
+ int major,
+ int minor,
+ long blocks,
+ long start_sect,
+ long nr_sects,
+ String name,
+ boolean xeno) {
+ this.major = major;
+ this.minor = minor;
+ this.blocks = blocks;
+ this.start_sect = start_sect;
+ this.nr_sects = nr_sects;
+ this.name = name;
+ this.xeno = xeno;
+ }
- public boolean equals(Object oth) {
- if (this == oth) {
- return true;
+ /**
+ * Dump this partition as XML.
+ * @param out The writer to dump to.
+ */
+ void dumpAsXML(PrintWriter out) {
+ out.println(
+ " <partition>\n"
+ + " <major>"
+ + major
+ + "</major>\n"
+ + " <minor>"
+ + minor
+ + "</minor>\n"
+ + " <blocks>"
+ + blocks
+ + "</blocks>\n"
+ + " <start_sect>"
+ + start_sect
+ + "</start_sect>\n"
+ + " <nr_sects>"
+ + nr_sects
+ + "</nr_sects>\n"
+ + " <name>"
+ + name
+ + "</name>\n"
+ + " </partition>");
}
- if (oth == null) {
- return false;
+ /**
+ * @return Major device number.
+ */
+ public int getMajor() {
+ return major;
}
- if (oth.getClass() != getClass()) {
- return false;
+ /**
+ * @return Minor device number.
+ */
+ public int getMinor() {
+ return minor;
}
- Partition other = (Partition) oth;
+ /**
+ * @return Number of blocks.
+ */
+ public long getBlocks() {
+ return blocks;
+ }
- if (this.major != other.major) {
- return false;
+ /**
+ * @return Starting sector.
+ */
+ public long getStartSect() {
+ return start_sect;
}
- if (this.minor != other.minor) {
- return false;
+ /**
+ * @return Number of sectors.
+ */
+ public long getNumSects() {
+ return nr_sects;
}
- if (this.blocks != other.blocks) {
- return false;
+ /**
+ * @return Name of partition.
+ */
+ public String getName() {
+ return name;
}
- if (this.start_sect != other.start_sect) {
- return false;
+ /**
+ * @return True if this is a XenoPartition.
+ */
+ public boolean isXeno() {
+ return xeno;
}
- if (this.nr_sects != other.nr_sects) {
- return false;
+ /**
+ * Is this partition identical to the other?
+ * @param other Other partition to compare to.
+ * @return True if they are identical.
+ */
+ public boolean identical(Partition other) {
+ return this.major == other.major
+ && this.minor == other.minor
+ && this.blocks == other.blocks
+ && this.start_sect == other.start_sect
+ && this.nr_sects == other.nr_sects
+ && this.name.equals(other.name);
}
- if (this.name == null) {
- if (other.name != null) {
- return false;
- }
- } else {
- if (!this.name.equals(other.name)) {
- return false;
- }
+
+ /**
+ * @return An Extent covering this partiton.
+ */
+ public Extent toExtent() {
+ return new Extent(getDisk(),start_sect,nr_sects);
}
- return true;
- }
-
- /**
- * @return An Extent covering this partiton.
- */
- public Extent toExtent()
- {
- Extent e = new Extent();
- // Build 16-bit disk number.. high 8 bits are the major
- e.disk = major << 8;
- // Low 8 bits are the minor, but bottom 5 need to be cleared
- // as they are the partition number, not the disk number
- e.disk |= ( minor & 0xE0 );
- e.offset = start_sect;
- e.size = nr_sects;
- return e;
- }
-
- /**
- * @param e Extent to compare this partition to.
- * @return True if this partition covers the same disk area as the given extent.
- */
- public boolean matchesExtent( Extent e )
- {
- if ( e.getMajor() != major )
- return false;
- if ( e.getMinor() != minor )
- return false;
- if ( e.offset != start_sect )
- return false;
- if ( e.size != nr_sects )
- return false;
-
- return true;
- }
+ /**
+ * @param e Extent to compare this partition to.
+ * @return True if this partition covers the same disk area as the given extent.
+ */
+ public boolean matchesExtent(Extent e) {
+ return e.getDisk() == getDisk()
+ && e.getOffset() == start_sect
+ && e.getSize() == nr_sects;
+ }
+
+ /**
+ * @return Disk number for this partition.
+ */
+ public int getDisk() {
+ if ( name.startsWith("hd") ) {
+ // High 8 bits are major, low 8 bits are minor, with bottom 6 clear
+ return (major << 8) | (minor & 0xC0);
+ } else if ( name.startsWith("sd") ) {
+ // High 8 bits are major, low 8 bits are minor, with bottom 4 clear
+ return (major << 8) | (minor & 0xF0);
+ } else {
+ throw new IllegalArgumentException("Don't know how to convert " + name + "into a disk number");
+ }
+ }
}
* PartitionManager manages the partitions on the machine. It is a Singleton
* which automatically initialises itself on first class reference.
*/
-public class
-PartitionManager
-{
- static final String proc_template =
- "major minor #blocks start_sect nr_sects name";
-
- public static final PartitionManager it = new PartitionManager(Settings.PARTITIONS_FILE);
-
- Vector partition_map;
-
- /*
- * Initialize partition manager with source file.
- * Normally we read from /proc/partitions, but we can
- * specify an alternative file for debugging
- */
- private PartitionManager (String filename)
- {
- String str;
- BufferedReader in;
-
- partition_map = new Vector(100,10);
-
- try
- {
- in = new BufferedReader(new FileReader(filename));
-
- str = in.readLine(); /* skip headings */
- if (str.length() < proc_template.length() ||
- !str.substring(0, proc_template.length()).equals(proc_template))
- {
- System.err.println ("Error: Incorrect /proc/partitions.");
- System.err.println (" Is this Xeno?");
- System.exit (1);
- }
-
- str = in.readLine(); /* skip blank line */
-
- str = in.readLine();
- while (str != null)
- {
- Partition partition = new Partition();
-
- partition.major = Integer.parseInt(str.substring(0,5).trim());
- partition.minor = Integer.parseInt(str.substring(5,10).trim());
- partition.blocks = Integer.parseInt(str.substring(10,21).trim());
- partition.start_sect = Integer.parseInt(str.substring(21,32).trim());
- partition.nr_sects = Integer.parseInt(str.substring(32,43).trim());
- partition.name = str.substring(43).trim();
- partition.xeno = false;
-
- partition_map.add(partition);
- str = in.readLine();
- }
+public class PartitionManager {
+ /** The proc header string, used to check that this is a suitable proc file. */
+ private static final String PROC_TEMPLATE =
+ "major minor #blocks start_sect nr_sects name";
+
+ /** The single PartitionManager reference. */
+ public static final PartitionManager IT =
+ new PartitionManager(Settings.PARTITIONS_FILE);
+
+ /** The list of partitions. */
+ private Vector partition_map;
+
+ /**
+ * Initialize partition manager with source file.
+ * Normally we read from /proc/partitions, but we can
+ * specify an alternative file for debugging.
+ * @param filename The file to read partition data from.
+ */
+ private PartitionManager(String filename) {
+ String str;
+ BufferedReader in;
+
+ partition_map = new Vector(100, 10);
+
+ try {
+ in = new BufferedReader(new FileReader(filename));
+
+ str = in.readLine(); /* skip headings */
+ if (str.length() < PROC_TEMPLATE.length()
+ || !str.substring(0, PROC_TEMPLATE.length()).equals(
+ PROC_TEMPLATE)) {
+ System.err.println("Error: Incorrect /proc/partitions.");
+ System.err.println(" Is this Xeno?");
+ System.exit(1);
+ }
+
+ str = in.readLine(); /* skip blank line */
+
+ str = in.readLine();
+ while (str != null) {
+ Partition partition =
+ new Partition(
+ Integer.parseInt(str.substring(0, 5).trim()),
+ Integer.parseInt(str.substring(5, 10).trim()),
+ Integer.parseInt(str.substring(10, 21).trim()),
+ Integer.parseInt(str.substring(21, 32).trim()),
+ Integer.parseInt(str.substring(32, 43).trim()),
+ str.substring(43).trim(),
+ false);
+
+ partition_map.add(partition);
+ str = in.readLine();
+ }
+ } catch (IOException io) {
+ System.err.println(
+ "PartitionManager: error reading partition file ["
+ + filename
+ + "]");
+ System.err.println(io);
+ }
}
- catch (IOException io)
- {
- System.err.println ("PartitionManager: error reading partition file ["
- + filename + "]");
- System.err.println (io);
+
+ /**
+ * Find a partition with the specified name.
+ * @param name The name to search for.
+ * @return The partition found, or null if no such partition.
+ */
+ public Partition getPartition(String name) {
+ Partition partition = null;
+ for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+ partition = (Partition) e.nextElement();
+ if (partition.getName().equals(name)) {
+ return partition;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds the partition that matches the given extent, if any.
+ * @param extent The extent to compare to.
+ * @return The first matching partition, or null if none.
+ */
+ public Partition getPartition(Extent extent) {
+ Partition partition = null;
+ for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+ partition = (Partition) e.nextElement();
+ if (partition.matchesExtent(extent)) {
+ return partition;
+ }
+ }
+ return null;
}
- }
-
- public Partition
- get_partition (String name)
- {
- Partition partition = null;
- for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
- {
- partition = (Partition) e.nextElement();
- if (partition.name.equals(name))
- {
- return partition;
- }
+
+ /**
+ * Find the ith partition in the partition list.
+ * @param i Index number.
+ * @return The partition, or null if out of range.
+ */
+ public Partition getPartition(int i) {
+ if ( i >= partition_map.size() ) {
+ return null;
+ }
+ return (Partition) partition_map.elementAt( i );
}
- return null;
- }
-
- /**
- * Finds the partition that matches the given extent, if any.
- * @param extent The extent to compare to.
- * @return The first matching partition, or null if none.
- */
- public Partition
- get_partition (Extent extent)
- {
- Partition partition = null;
- for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
- {
- partition = (Partition) e.nextElement();
- if (partition.matchesExtent(extent))
- {
- return partition;
- }
+
+ /**
+ * Adds the given partition as a XenoPartition.
+ * @param p The partition to add.
+ */
+ void addXenoPartition(Partition p) {
+ for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+ Partition partition = (Partition) e.nextElement();
+ if (partition.identical(p)) {
+ partition.makeXeno();
+ }
+ }
}
- return null;
- }
-
- Partition
- get_partition (int index)
- {
- return (Partition) partition_map.get(index);
- }
-
- void
- add_xeno_partition (Partition p)
- {
- for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
- {
- Partition partition = (Partition) e.nextElement();
- if (partition.equals(p))
- {
- partition.xeno = true;
- }
+
+ /**
+ * Dump the XenoPartition list as XML.
+ * @param out Writer to dump to.
+ */
+ void dumpAsXML(PrintWriter out) {
+ out.println("<partitions>");
+ for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+ Partition partition = (Partition) e.nextElement();
+ if (partition.isXeno()) {
+ partition.dumpAsXML(out);
+ }
+ }
+
+ out.println("</partitions>");
+
+ return;
}
- }
-
- /*
- * dump the xeno partition list as xml
- */
- void
- dump_xml (PrintWriter out)
- {
- out.println("<partitions>");
- for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;)
- {
- Partition partition = (Partition) e.nextElement();
- if (partition.xeno == true)
- {
- partition.dump_xml(out);
- }
+
+ /**
+ * @return The number of partitions.
+ */
+ public int getPartitionCount() {
+ return partition_map.size();
}
- out.println("</partitions>");
-
- return;
- }
-
- /**
- * get the number of partitions
- */
-
- int
- getPartitionCount ()
- {
- return partition_map.size();
- }
-
- /**
- * get the details about a particular partition
- *
- */
- Partition
- getPartition (int index)
- {
- Partition partition = (Partition) partition_map.get(index);
- return partition;
- }
-
- /**
- * Get an iterator over all the partitions.
- * @return An iterator over Partition objects.
- */
- public Iterator iterator()
- {
- return partition_map.iterator();
- }
+ /**
+ * Get an iterator over all the partitions.
+ * @return An iterator over Partition objects.
+ */
+ public Iterator iterator() {
+ return partition_map.iterator();
+ }
}
* The Settings class is a repository for global settings such as the IP of
* the machine and the location of the defaults file.
*/
-public final class Settings
-{
- public static final String DEFAULTS_FILE = System.getProperty ("DEFAULTS_FILE", "domctl.xml");
- public static final String DEFAULTS_PATH = System.getProperty ("DEFAULTS_PATH", ".:/etc:/var/lib/xen");
- public static final String LOCAL_IP = System.getProperty ("LOCAL_IP");
- public static final String LOCAL_MASK = System.getProperty ("LOCAL_MASK");
- public static final String LOCAL_GW = System.getProperty ("LOCAL_ROUTE");
- public static final boolean TEST = (System.getProperty ("TEST") != null);
- public static final String XI_HELPER = System.getProperty ("XI_HELPER", "xi_helper");
- public static final String PARTITIONS_FILE = System.getProperty("PARTITIONS_FILE", "/proc/partitions");
- public static final String STATE_INPUT_FILE = System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml");
- public static final String STATE_OUTPUT_FILE = System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml");
- public static final int SECTOR_SIZE = Integer.parseInt( System.getProperty("SECTOR_SIZE", "512") );
+public final class Settings {
+ /** Filename for the defaults file. */
+ public static final String DEFAULTS_FILE =
+ System.getProperty("DEFAULTS_FILE", "domctl.xml");
+ /** Path to search for the defaults file. */
+ public static final String DEFAULTS_PATH =
+ System.getProperty("DEFAULTS_PATH", ".:/etc:/var/lib/xen");
+ /** IP address of domain 0. */
+ public static final String LOCAL_IP = System.getProperty("LOCAL_IP");
+ /** Network mask of domain 0. */
+ public static final String LOCAL_MASK = System.getProperty("LOCAL_MASK");
+ /** Gateway of domain 0. */
+ public static final String LOCAL_GW = System.getProperty("LOCAL_ROUTE");
+ /** If set, do not call any xi_ commands, just print their command lines. */
+ public static final boolean TEST = (System.getProperty("TEST") != null);
+ /** Name of xi_helper utility. */
+ public static final String XI_HELPER =
+ System.getProperty("XI_HELPER", "xi_helper");
+ /** File to parse to get partition info. */
+ public static final String PARTITIONS_FILE =
+ System.getProperty("PARTITIONS_FILE", "/proc/partitions");
+ /** File to load virtual disk state from. */
+ public static final String STATE_INPUT_FILE =
+ System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml");
+ /** File to save virtual disk state to. */
+ public static final String STATE_OUTPUT_FILE =
+ System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml");
+ /** Size of a sector in bytes. */
+ public static final int SECTOR_SIZE =
+ Integer.parseInt(System.getProperty("SECTOR_SIZE", "512"));
- public static File getDefaultsFile() {
- StringTokenizer tok = new StringTokenizer (DEFAULTS_PATH, ":");
- File result = null;
- File probe;
+ /**
+ * Search for the defaults file in the path configured in DEFAULTS_PATH.
+ * @return Reference to the defaults file.
+ */
+ public static File getDefaultsFile() {
+ StringTokenizer tok = new StringTokenizer(DEFAULTS_PATH, ":");
+ File result = null;
+ File probe;
- while (tok.hasMoreTokens ()) {
- String probe_dir = tok.nextToken ();
- probe = new File (probe_dir, DEFAULTS_FILE);
- if (probe.exists ()) {
- result = probe;
- break;
- }
- }
+ while (tok.hasMoreTokens()) {
+ String probe_dir = tok.nextToken();
+ probe = new File(probe_dir, DEFAULTS_FILE);
+ if (probe.exists()) {
+ result = probe;
+ break;
+ }
+ }
- if (result == null) {
- System.err.println ("Could not find " + DEFAULTS_FILE + " in path " + DEFAULTS_PATH);
- }
+ if (result == null) {
+ System.err.println(
+ "Could not find "
+ + DEFAULTS_FILE
+ + " in path "
+ + DEFAULTS_PATH);
+ }
- return result;
- }
+ return result;
+ }
}
package org.xenoserver.control;
-public class StringPattern
-{
- String base;
- int bn;
- boolean addDom;
- boolean appendDom;
+/**
+ * This utility class expands configuration file patterns.
+ */
+public class StringPattern {
+ /** The base string for this pattern. */
+ private String base;
+ /** The base number for this pattern. */
+ private int bn;
+ /** If true, add the domain number to the base number and append. */
+ private boolean addDom;
+ /** If true, append the domain number to the base string. */
+ private boolean appendDom;
- static StringPattern parse (String t)
- {
- StringPattern result = new StringPattern ();
- char[] ca = t.toCharArray ();
- int idx = 0;
- int len = ca.length;
+ /**
+ * Parse a string into a pattern.
+ * @param t The pattern string to parse.
+ * @return A usable pattern object.
+ */
+ static StringPattern parse(String t) {
+ StringPattern result = new StringPattern();
+ char[] ca = t.toCharArray();
+ int idx = 0;
+ int len = ca.length;
- if (len == 0) {
- result.base = "";
- result.bn = 0;
- result.addDom = false;
- } else if (ca[len - 1] == '+') {
- idx = len - 2;
- if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
- while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
- idx --;
- }
- result.base = t.substring(0, idx + 1);
- result.bn = Integer.parseInt (t.substring (idx + 1, len - 1));
- result.addDom = true;
- } else {
- result.base = t.substring(0, len - 1);
- result.appendDom = true;
- }
- } else {
- result.base = t;
- }
+ if (len == 0) {
+ result.base = "";
+ result.bn = 0;
+ result.addDom = false;
+ } else if (ca[len - 1] == '+') {
+ idx = len - 2;
+ if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+ while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+ idx--;
+ }
+ result.base = t.substring(0, idx + 1);
+ result.bn = Integer.parseInt(t.substring(idx + 1, len - 1));
+ result.addDom = true;
+ } else {
+ result.base = t.substring(0, len - 1);
+ result.appendDom = true;
+ }
+ } else {
+ result.base = t;
+ }
- return result;
- }
+ return result;
+ }
- public String resolve (int domain_id) {
- if (addDom) {
- return base + (bn + domain_id);
- } else if (appendDom) {
- return base + domain_id;
- } else {
- return base;
+ /**
+ * Resolve the pattern for the given domain number.
+ * @param domain The domain number to use.
+ * @return The expanded pattern for the given domain.
+ */
+ String resolve(int domain) {
+ if (addDom) {
+ return base + (bn + domain);
+ } else if (appendDom) {
+ return base + domain;
+ } else {
+ return base;
+ }
}
- }
- public String toString () {
- return ("[" +
- base +
- (addDom ? "+" + bn : "") +
- ((addDom || appendDom) ? "+ID" : "") +
- "]");
- }
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return (
+ "["
+ + base
+ + (addDom ? "+" + bn : "")
+ + ((addDom || appendDom) ? "+ID" : "")
+ + "]");
+ }
}
import java.io.PrintWriter;
+/**
+ * A virtual block device; a mapping from a domain-specific number to a virtual
+ * disk with associated access mode.
+ */
public class VirtualBlockDevice {
- String key;
- int domain;
- int vbdnum;
- Mode mode; /* rw or ro */
-
- String dump(boolean title) {
- StringBuffer sb = new StringBuffer();
-
- if (title) {
- sb.append(" key dom vbd mode\n");
- } else {
- sb.append(
- " "
- + key
- + " "
- + Library.format(domain, 3, 0)
- + " "
- + Library.format(vbdnum, 3, 0)
- + " "
- + mode.toString()
- + "\n");
+ /** The virtual disk which this block device maps onto. */
+ private VirtualDisk vd;
+ /** The domain in which this block device exists. */
+ private int domain;
+ /** The block device number in that domain. */
+ private int vbdNum;
+ /** The access mode within that domain. */
+ private Mode mode;
+
+ /**
+ * Constructor for VirtualBlockDevice.
+ * @param vd The virtual disk to map to.
+ * @param domain The domain to create the device in.
+ * @param vbdNum The number for the device.
+ * @param mode The access mode.
+ */
+ VirtualBlockDevice(
+ VirtualDisk vd,
+ int domain,
+ int vbdNum,
+ Mode mode) {
+ this.vd = vd;
+ this.domain = domain;
+ this.vbdNum = vbdNum;
+ this.mode = mode;
+ }
+
+ // TODO: get rid of this method
+ String dump(boolean title) {
+ StringBuffer sb = new StringBuffer();
+
+ if (title) {
+ sb.append(" key dom vbd mode\n");
+ } else {
+ sb.append(
+ " "
+ + vd.getKey()
+ + " "
+ + Library.format(domain, 3, false)
+ + " "
+ + Library.format(vbdNum, 3, false)
+ + " "
+ + mode.toString()
+ + "\n");
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Dump the virtual block device as XML.
+ * @param out The writer to dump to.
+ */
+ void dumpAsXML(PrintWriter out) {
+ out.println(" <virtual_block_device>");
+ out.println(" <key>" + vd.getKey() + "</key>");
+ out.println(" <domain>" + domain + "</domain>");
+ out.println(" <vbdnum>" + vbdNum + "</vbdnum>");
+ out.println(" <mode>" + mode + "</mode>");
+ out.println(" </virtual_block_device>");
}
- return sb.toString();
- }
-
- void dump_xml(PrintWriter out) {
- out.println(" <virtual_block_device>");
- out.println(" <key>" + key + "</key>");
- out.println(" <domain>" + domain + "</domain>");
- out.println(" <vbdnum>" + vbdnum + "</vbdnum>");
- out.println(" <mode>" + mode + "</mode>");
- out.println(" </virtual_block_device>");
- }
-
- public String getKey() {
- return key;
- }
-
- public int getDomain() {
- return domain;
- }
-
- public int getVBDNum() {
- return vbdnum;
- }
-
- public Mode getMode() {
- return mode;
- }
+ /**
+ * @return This device's virtual disk.
+ */
+ public VirtualDisk getVirtualDisk() {
+ return vd;
+ }
+
+ /**
+ * @return The domain this device exists in.
+ */
+ public int getDomain() {
+ return domain;
+ }
+
+ /**
+ * @return The device number within its domain.
+ */
+ public int getVbdNum() {
+ return vbdNum;
+ }
+
+ /**
+ * @return This device's access mode.
+ */
+ public Mode getMode() {
+ return mode;
+ }
}
import java.util.Iterator;
import java.util.Vector;
+/**
+ * A single virtual disk. This may be used by multiple virtual block devices.
+ */
public class VirtualDisk {
- String name;
- String key;
- Date expiry;
- Vector extents;
-
- VirtualDisk(String name, Date expiry, String key) {
- this.name = name;
- if ( key == null )
- this.key = generate_key();
- else
- this.key = key;
- this.expiry = expiry;
- extents = new Vector();
- }
-
- VirtualDisk(String name) {
- this(name, null, null);
- }
-
- VirtualDisk(String name, Date expiry) {
- this(name, expiry, null);
- }
-
- /*
- * generate a unique key for this virtual disk.
- * for now, just generate a 10 digit number
- */
- String generate_key() {
- return Long.toString(1000000000l + (long) (Math.random() * 8999999999l));
- }
-
- void set_expiry(Date expiry) {
- this.expiry = expiry;
- }
-
- public void add_extent(Extent extent) {
- extents.add(extent);
- }
-
- public Extent remove_extent() {
- Extent e;
-
- if (extents.size() > 0) {
- e = (Extent) extents.remove(0);
- } else {
- e = null;
- }
-
- return e;
- }
-
- String dump_xen(VirtualBlockDevice vbd) {
- StringBuffer sb = new StringBuffer();
-
- sb.append(
- "domain:"
- + vbd.domain
- + " "
- + vbd.mode.toString()
- + " "
- + "segment:"
- + vbd.vbdnum
- + " "
- + "extents:"
- + extents.size()
- + " ");
- for (int loop = 0; loop < extents.size(); loop++) {
- Extent e = (Extent) extents.get(loop);
- sb.append(
- "(disk:"
- + e.disk
- + " "
- + "offset:"
- + e.offset
- + " "
- + "size:"
- + e.size
- + ")");
- }
- return sb.toString();
- }
-
- void dump_xml(PrintWriter out) {
- out.println(" <virtual_disk>");
- out.println(" <name>" + name + "</name>");
- out.println(" <key>" + key + "</key>");
- if (expiry == null) {
- out.println(" <expiry>0</expiry>");
- } else {
- out.println(" <expiry>" + expiry.getTime() + "</expiry>");
- }
- out.println(" <extents>");
- for (int loop = 0; loop < extents.size(); loop++) {
- Extent e = (Extent) extents.get(loop);
- out.println(" <extent>");
- out.println(" <disk>" + e.disk + "</disk>");
- out.println(" <size>" + e.size + "</size>");
- out.println(" <offset>" + e.offset + "</offset>");
- out.println(" </extent>");
- }
- out.println(" </extents>");
- out.println(" </virtual_disk>");
-
- return;
- }
-
- /*
- * Add a partition as a XenoPartition.
- * Chop the partition in to extents and of size "size" sectors
- * and add them to the virtual disk.
- */
-
- void add_new_partition(Partition partition, long size) {
- int loop;
-
- for (loop = 0; loop < partition.nr_sects / size; loop++) {
- Extent extent = new Extent();
-
- extent.disk = partition.major << 8;
- extent.disk = extent.disk | (partition.minor >> 5) << 5;
- extent.size = size;
- extent.offset = partition.start_sect + (size * loop);
-
- add_extent(extent);
- }
-
- return;
- }
-
- public String getName() {
- return name;
- }
-
- public String getKey() {
- return key;
- }
-
- public Date getExpiry() {
- return expiry;
- }
-
- public int getExtentCount() {
- return extents.size();
- }
-
- public Extent getExtent(int index) {
- return (Extent) extents.get(index);
- }
-
- /**
- * @return Total size of this virtual disk in sectors.
- */
- public long getSize() {
- long size = 0;
- Iterator i = extents.iterator();
- while ( i.hasNext() ) {
- size += ((Extent) i.next()).getSize();
- }
- return size;
- }
-
- /**
- * @return An iterator over all extents in the disk.
- */
- public Iterator iterator() {
- return extents.iterator();
- }
+ /** The name of this virtual disk. */
+ private String name;
+ /** The key of this virtual disk (unique). */
+ private String key;
+ /** The expiry time of this virtual disk, or null for never. */
+ private Date expiry;
+ /** The extent list for this virtual disk. */
+ private Vector extents;
+
+ /**
+ * Construct a new virtual disk, specifying all parameters.
+ * @param name Name of the new disk.
+ * @param expiry Expiry time, or null for never.
+ * @param key Key for the new disk, or null to autogenerate.
+ */
+ VirtualDisk(String name, Date expiry, String key) {
+ this.name = name;
+ if (key == null) {
+ this.key = generateKey();
+ } else {
+ this.key = key;
+ }
+ this.expiry = expiry;
+ extents = new Vector();
+ }
+
+ /**
+ * Construct a new virtual disk, with automatically generated key and no expiry.
+ * @param name Name of the new disk.
+ */
+ VirtualDisk(String name) {
+ this(name, null, null);
+ }
+
+ /**
+ * Construct a new virtual disk, with automatically generated key.
+ * @param name Name of the new disk.
+ * @param expiry Expiry time, or null for never.
+ */
+ VirtualDisk(String name, Date expiry) {
+ this(name, expiry, null);
+ }
+
+ /**
+ * Generate a unique key for this virtual disk.
+ * For now, just generate a 10 digit number.
+ * @return A unique key.
+ */
+ private static String generateKey() {
+ return Long.toString(
+ 1000000000L + (long) (Math.random() * 8999999999L));
+ }
+
+ /**
+ * Add an extent to this disk.
+ * @param extent The extent to add.
+ */
+ void addExtent(Extent extent) {
+ extents.add(extent);
+ }
+
+ /**
+ * Remove the first extent from this disk.
+ * @return The extent removed, or null if there are no extents.
+ */
+ Extent removeExtent() {
+ Extent e;
+
+ if (extents.size() > 0) {
+ e = (Extent) extents.remove(0);
+ } else {
+ e = null;
+ }
+
+ return e;
+ }
+
+ /**
+ * Form a string suitable for passing into the XenoLinux proc interface mapping
+ * the given VBD to this virtual disk.
+ * @param vbd The virtual block device to map.
+ * @return A XenoLinux /proc string.
+ */
+ String dumpForXen(VirtualBlockDevice vbd) {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(
+ "domain:"
+ + vbd.getDomain()
+ + " "
+ + vbd.getMode().toString()
+ + " "
+ + "segment:"
+ + vbd.getVbdNum()
+ + " "
+ + "extents:"
+ + extents.size()
+ + " ");
+ for (int loop = 0; loop < extents.size(); loop++) {
+ Extent e = (Extent) extents.get(loop);
+ sb.append(
+ "(disk:"
+ + e.getDisk()
+ + " "
+ + "offset:"
+ + e.getOffset()
+ + " "
+ + "size:"
+ + e.getSize()
+ + ")");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Dump the virtual disk as XML.
+ * @param out The writer to dump to.
+ */
+ void dumpAsXML(PrintWriter out) {
+ out.println(" <virtual_disk>");
+ out.println(" <name>" + name + "</name>");
+ out.println(" <key>" + key + "</key>");
+ if (expiry == null) {
+ out.println(" <expiry>0</expiry>");
+ } else {
+ out.println(" <expiry>" + expiry.getTime() + "</expiry>");
+ }
+ out.println(" <extents>");
+ for (int loop = 0; loop < extents.size(); loop++) {
+ Extent e = (Extent) extents.get(loop);
+ out.println(" <extent>");
+ out.println(" <disk>" + e.getDisk() + "</disk>");
+ out.println(" <size>" + e.getSize() + "</size>");
+ out.println(" <offset>" + e.getOffset() + "</offset>");
+ out.println(" </extent>");
+ }
+ out.println(" </extents>");
+ out.println(" </virtual_disk>");
+
+ return;
+ }
+
+ /**
+ * Add a partition as a XenoPartition.
+ * Chop the partition in to extents and add them to this virtual disk.
+ * @param partition The partition to add.
+ * @param extentSize The number of sectors to use for each extent.
+ */
+ void addPartition(Partition partition, long extentSize) {
+ int loop;
+
+ for (loop = 0; loop < partition.getNumSects() / extentSize; loop++) {
+ Extent extent =
+ new Extent(
+ partition.getDisk(),
+ extentSize,
+ partition.getStartSect() + (extentSize * loop));
+
+ addExtent(extent);
+ }
+ }
+
+ /**
+ * @return The name of this virtual disk.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return The key of this virtual disk.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * @return The expiry time of this virtual disk.
+ */
+ public Date getExpiry() {
+ return expiry;
+ }
+
+ /**
+ * @return The number of extents in this virtual disk.
+ */
+ public int getExtentCount() {
+ return extents.size();
+ }
+
+ /**
+ * @return Total size of this virtual disk in sectors.
+ */
+ public long getSize() {
+ long size = 0;
+ Iterator i = extents.iterator();
+ while (i.hasNext()) {
+ size += ((Extent) i.next()).getSize();
+ }
+ return size;
+ }
+
+ /**
+ * @return An iterator over all extents in the disk.
+ */
+ public Iterator extents() {
+ return extents.iterator();
+ }
+
+ /**
+ * Reset the expiry time for this virtual disk.
+ * @param expiry The new expiry time, or null for never.
+ */
+ public void refreshExpiry(Date expiry) {
+ this.expiry = expiry;
+ }
}
import java.io.PrintWriter;
import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
/**
* VirtualDiskManager manages the list of virtual disks on the machine. It is
* a Singleton which automatically initialises itself on first class reference.
*/
public class VirtualDiskManager {
- public static final VirtualDiskManager it = new VirtualDiskManager();
- VirtualDisk free_disk;
- Vector virtual_disks;
- Hashtable virtual_block_devices;
- Hashtable key_hash;
-
- private VirtualDiskManager() {
- free_disk = new VirtualDisk("free");
-
- virtual_disks = new Vector(10, 5);
- flush_virtual_block_devices();
- key_hash = new Hashtable(100);
- }
-
- public VirtualDisk get_virtual_disk_key(String key) {
- return ((VirtualDisk) key_hash.get(key));
- }
-
- public void add_xeno_partition(Partition partition, long size) {
- free_disk.add_new_partition(partition, size);
- return;
- }
-
- /*
- * create a new virtual disk
- */
-
- public VirtualDisk create_virtual_disk(String name, long size, Date expiry) {
- VirtualDisk vd = new VirtualDisk(name, expiry);
-
- if ( free_disk.getSize() < size )
- return null;
-
- while (size > 0) {
- Extent e;
-
- e = free_disk.remove_extent();
- if (e == null) {
- return null;
- }
- size -= e.size;
- vd.add_extent(e);
- }
-
- add_virtual_disk(vd);
-
- return vd;
- }
-
- /*
- * delete a new virtual disk. extents go back into the free pool
- */
-
- public void delete_virtual_disk(String key) {
- VirtualDisk vd;
-
- vd = (VirtualDisk) key_hash.get(key);
- if (vd != null) {
- Extent e;
-
- key_hash.remove(key);
- virtual_disks.remove(vd);
-
- e = vd.remove_extent();
- while (e != null) {
- free_disk.add_extent(e);
- e = vd.remove_extent();
- }
- }
- return;
- }
-
- /*
- * reset the expiry time for a virtual disk
- */
-
- public void refresh_virtual_disk(String key, Date expiry) {
- VirtualDisk vd = (VirtualDisk) key_hash.get(key);
- if (vd != null) {
- vd.set_expiry(expiry);
- }
- }
-
- /*
- * create a new virtual block device
- */
- public VirtualBlockDevice create_virtual_block_device(
- String key,
- int domain,
- int vbd_num,
- String mode) {
- VirtualBlockDevice vbd = new VirtualBlockDevice();
- VirtualDisk vd = get_virtual_disk_key(key);
-
- if (vd == null) {
- System.err.println(
- "create virtual block device error: unknown key " + "[" + key + "]");
- return null;
- }
-
- vbd.key = key;
- vbd.domain = domain;
- vbd.vbdnum = vbd_num;
-
- if (mode.equals(Mode.READ_ONLY.toString())
- || mode.equals("RO")
- || mode.equals("ro")) {
- vbd.mode = Mode.READ_ONLY;
- } else if (
- mode.equals(Mode.READ_WRITE.toString())
- || mode.equals("RW")
- || mode.equals("rw")) {
- vbd.mode = Mode.READ_WRITE;
- } else {
- System.err.println(
- "create virtual block device error: unknown mode " + "[" + mode + "]");
- return null;
- }
-
- add_virtual_block_device(vbd);
-
- return vbd;
- }
-
- /*
- * delete a virtual block device
- */
- public void delete_virtual_block_device(int domain, int vbd_num) {
- Object hash = get_vbd_hash(domain, vbd_num);
- virtual_block_devices.remove(hash);
- }
-
- /*
- * flush all virtual block devices
- */
- public void flush_virtual_block_devices() {
- /* isn't automatic garbage collection wonderful? */
- virtual_block_devices = new Hashtable(100);
- }
-
- public void add_virtual_disk(VirtualDisk vd) {
- virtual_disks.add(vd);
- key_hash.put(vd.getKey(), vd);
- }
-
- public void add_virtual_block_device(VirtualBlockDevice vbd) {
- Object hash = get_vbd_hash(vbd.domain, vbd.vbdnum);
- virtual_block_devices.put(hash, vbd);
- }
-
- Object get_vbd_hash(int domain, int vbd_num) {
- return new Integer(domain * 16 + vbd_num);
- }
-
- public void add_free(VirtualDisk vd) {
- free_disk = vd;
- }
-
- public String dump_virtualblockdevices() {
- StringBuffer sb = new StringBuffer();
- boolean first = true;
-
- for (Enumeration enumeration = virtual_block_devices.elements();
- enumeration.hasMoreElements();
- ) {
- VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
- if (first) {
- sb.append(vbd.dump(true));
- first = false;
- }
-
- sb.append(vbd.dump(false));
- }
-
- return sb.toString();
- }
-
- public void dump_xml(PrintWriter out) {
- out.println("<free>");
- free_disk.dump_xml(out);
- out.println("</free>");
- out.println("<virtual_disks>");
- for (int i = 0; i < virtual_disks.size(); i++) {
- VirtualDisk vd = (VirtualDisk) virtual_disks.get(i);
- vd.dump_xml(out);
- }
- out.println("</virtual_disks>");
- out.println("<virtual_block_devices>");
- for (Enumeration enumeration = virtual_block_devices.elements();
- enumeration.hasMoreElements();
- ) {
- VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
- vbd.dump_xml(out);
- }
-
- out.println("</virtual_block_devices>");
-
- return;
- }
-
- /*************************************************************************/
-
- public int getVirtualDiskCount() {
- return virtual_disks.size();
- }
-
- public VirtualDisk getVirtualDisk(int index) {
- return (VirtualDisk) virtual_disks.get(index);
- }
-
- public VirtualDisk getFreeVirtualDisk() {
- return free_disk;
- }
-
- public Enumeration getVirtualBlockDevices() {
- return virtual_block_devices.elements();
- }
+ /** The single VDM reference. */
+ public static final VirtualDiskManager IT = new VirtualDiskManager();
+ /** The free-space disk. */
+ private VirtualDisk freeDisk;
+ /** The map of keys to virtual disks. */
+ private LinkedHashMap virtualDisks = new LinkedHashMap(100);
+ /** The map of (domain,vbdnum) to virtual block devices. */
+ private LinkedHashMap virtualBlockDevices = new LinkedHashMap(100);
+
+ /**
+ * VDM constructor, private as it's a singleton.
+ */
+ private VirtualDiskManager() {
+ freeDisk = new VirtualDisk("free");
+ }
+
+ /**
+ * Get the virtual disk with the specified key.
+ * @param key The key to look for.
+ * @return The virtual disk, or null if not found.
+ */
+ public VirtualDisk getVirtualDisk(String key) {
+ return ((VirtualDisk) virtualDisks.get(key));
+ }
+
+ /**
+ * Add a new partition to the free space list in the disk manager.
+ * @param partition The partition to add.
+ * @param chunkSize The chunk size to split the partition into, in sectors.
+ */
+ public void addPartition(Partition partition, long chunkSize) {
+ freeDisk.addPartition(partition, chunkSize);
+ }
+
+ /**
+ * Create a new virtual disk.
+ * @param name The disk name to use.
+ * @param size The number of sectors to allocate.
+ * @param expiry The expiry time, or null for never.
+ * @return null if not enough space is available
+ */
+ public VirtualDisk createVirtualDisk(String name, long size, Date expiry) {
+ if (freeDisk.getSize() < size) {
+ return null;
+ }
+
+ VirtualDisk vd = new VirtualDisk(name, expiry);
+
+ while (size > 0) {
+ Extent e;
+
+ e = freeDisk.removeExtent();
+ if (e == null) {
+ return null;
+ }
+ size -= e.getSize();
+ vd.addExtent(e);
+ }
+
+ insertVirtualDisk(vd);
+
+ return vd;
+ }
+
+ /**
+ * Delete a virtual disk, and put its extents back into the free pool.
+ * @param key The key of the disk to delete.
+ */
+ public void deleteVirtualDisk(String key) {
+ VirtualDisk vd;
+
+ vd = (VirtualDisk) virtualDisks.get(key);
+ if (vd != null) {
+ Extent e;
+
+ virtualDisks.remove(key);
+
+ e = vd.removeExtent();
+ while (e != null) {
+ freeDisk.addExtent(e);
+ e = vd.removeExtent();
+ }
+ }
+ }
+
+ /**
+ * Create a new virtual block device.
+ * @param vd The virtual disk to expose.
+ * @param domain The domain to create the device for.
+ * @param vbdNum The block device number to use.
+ * @param mode The mode to create the device with.
+ * @return The newly created virtual block device.
+ */
+ public VirtualBlockDevice createVirtualBlockDevice(
+ VirtualDisk vd,
+ int domain,
+ int vbdNum,
+ Mode mode) {
+ VirtualBlockDevice vbd =
+ new VirtualBlockDevice(vd, domain, vbdNum, mode);
+
+ insertVirtualBlockDevice(vbd);
+
+ return vbd;
+ }
+
+ /**
+ * Delete a virtual block device.
+ * @param domain Domain owning the device.
+ * @param vbdNum The vbd number within the domain.
+ */
+ public void deleteVirtualBlockDevice(int domain, int vbdNum) {
+ Object hash = hashVBD(domain, vbdNum);
+ virtualBlockDevices.remove(hash);
+ }
+
+ /**
+ * Flush all virtual block devices.
+ */
+ public void flushVirtualBlockDevices() {
+ /* isn't automatic garbage collection wonderful? */
+ virtualBlockDevices = new LinkedHashMap(100);
+ }
+
+ /**
+ * Insert a new virtual disk into the map.
+ * @param vd The disk to insert.
+ */
+ void insertVirtualDisk(VirtualDisk vd) {
+ virtualDisks.put(vd.getKey(), vd);
+ }
+
+ /**
+ * Insert a new virtual block device into the map.
+ * @param vbd The device to insert.
+ */
+ void insertVirtualBlockDevice(VirtualBlockDevice vbd) {
+ Object hash = hashVBD(vbd.getDomain(), vbd.getVbdNum());
+ virtualBlockDevices.put(hash, vbd);
+ }
+
+ /**
+ * Hash a virtual block device.
+ * @param domain The VBD's domain.
+ * @param vbdNum The VBD's number within the domain.
+ * @return A suitable hash key.
+ */
+ Object hashVBD(int domain, int vbdNum) {
+ return new Integer(domain * 16 + vbdNum);
+ }
+
+ /**
+ * Set a new free disk.
+ * @param vd The free disk to set.
+ */
+ void setFreeDisk(VirtualDisk vd) {
+ freeDisk = vd;
+ }
+
+ /**
+ * Dump the data in the VirtualDiskManager in XML form.
+ * @param out The output writer to dump to.
+ */
+ void dumpAsXML(PrintWriter out) {
+ out.println("<free>");
+ freeDisk.dumpAsXML(out);
+ out.println("</free>");
+ out.println("<virtual_disks>");
+ Iterator i = virtualDisks.values().iterator();
+ while (i.hasNext()) {
+ VirtualDisk vd = (VirtualDisk) i.next();
+ vd.dumpAsXML(out);
+ }
+ out.println("</virtual_disks>");
+ out.println("<virtual_block_devices>");
+ i = virtualBlockDevices.values().iterator();
+ while (i.hasNext()) {
+ VirtualBlockDevice vbd = (VirtualBlockDevice) i.next();
+ vbd.dumpAsXML(out);
+ }
+
+ out.println("</virtual_block_devices>");
+ }
+
+ /**
+ * @return The free disk.
+ */
+ public VirtualDisk getFreeDisk() {
+ return freeDisk;
+ }
+
+ /**
+ * @return An iterator over the virtual block devices.
+ */
+ public Iterator getVirtualBlockDevices() {
+ return virtualBlockDevices.values().iterator();
+ }
+
+ /**
+ * @return An iterator over the virtual disks.
+ */
+ public Iterator getVirtualDisks() {
+ return virtualDisks.values().iterator();
+ }
}
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
-
-public class
-XML
-{
- static Document document = null;
- /*
- * dump partition manager and virtual disk manager state to filename
- */
-
- public static void
- dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
- {
- PrintWriter out;
+/**
+ * Utility class for loading and saving state through XML files.
+ */
+public class XML {
+ /** The document we are reading/writing. */
+ private static Document document = null;
- try
- {
- out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
- }
- catch (IOException e)
- {
- System.err.println ("XML.dump_state error [" + filename + "]");
- System.err.println (e);
- return;
- }
+ /**
+ * Save the state of the managers to the configuration file given.
+ * @param pm The PartitionManager to save.
+ * @param vdm The VirtualDiskManager to save.
+ * @param filename The configuration filename to save to.
+ */
+ public static void saveState(
+ PartitionManager pm,
+ VirtualDiskManager vdm,
+ String filename) {
+ PrintWriter out;
- out.println("<?xml version=\"1.0\"?>");
- out.println("<vdmanager>");
- pm.dump_xml(out);
- vdm.dump_xml(out);
- out.println("</vdmanager>");
+ try {
+ out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
+ } catch (IOException e) {
+ System.err.println("XML.dump_state error [" + filename + "]");
+ System.err.println(e);
+ return;
+ }
- out.close();
- return;
- }
+ out.println("<?xml version=\"1.0\"?>");
+ out.println("<vdmanager>");
+ pm.dumpAsXML(out);
+ vdm.dumpAsXML(out);
+ out.println("</vdmanager>");
- /*
- * load partition manager and virtual disk manager state from filename
- */
- public static void
- load_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
- {
- if (document == null)
- {
- load_file (filename);
+ out.close();
+ return;
}
- XMLHelper.parse(pm, vdm, document);
- }
+ /**
+ * Load the state of the managers from the given configuration file.
+ * @param pm The PartitionManager to load.
+ * @param vdm The VirtualDomainManager to load.
+ * @param filename The filename to read the configuration from.
+ */
+ public static void loadState(
+ PartitionManager pm,
+ VirtualDiskManager vdm,
+ String filename) {
+ if (document == null) {
+ loadFile(filename);
+ }
- /*
- * load XML from disk
- */
- static void
- load_file (String filename)
- {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- // factory.setNamespaceAware(true);
- // factory.setValidating(true);
+ XMLHelper.parse(pm, vdm, document);
+ }
- try
- {
- File file = new File(filename);
+ /**
+ * Load an XML file and parse it into a Document.
+ * @param filename The file to load.
+ */
+ private static void loadFile(String filename) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- document = builder.parse(file);
- }
- catch (SAXParseException spe) /* error generated by parser */
- {
- System.err.println ("xml parser exception on line " +
- spe.getLineNumber() +
- " for uri " + spe.getSystemId());
- System.err.println (spe.getMessage());
+ try {
+ File file = new File(filename);
- Exception x = spe;
- if (spe.getException() != null)
- x = spe.getException();
- x.printStackTrace();
- System.exit(1);
- }
- catch (SAXException sxe)
- {
- Exception e = sxe;
- if (sxe.getException() != null)
- e = sxe.getException();
- e.printStackTrace();
- System.exit(1);
- }
- catch (ParserConfigurationException pce)
- {
- pce.printStackTrace();
- }
- catch (FileNotFoundException fnfe)
- {
- System.err.println ("warning: state file not found [" +
- filename + "]");
- }
- catch (IOException ioe)
- {
- ioe.printStackTrace();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ document = builder.parse(file);
+ } catch (SAXParseException spe) /* error generated by parser */ {
+ System.err.println(
+ "xml parser exception on line "
+ + spe.getLineNumber()
+ + " for uri "
+ + spe.getSystemId());
+ System.err.println(spe.getMessage());
+
+ Exception x = spe;
+ if (spe.getException() != null) {
+ x = spe.getException();
+ }
+ x.printStackTrace();
+ System.exit(1);
+ } catch (SAXException sxe) {
+ Exception e = sxe;
+ if (sxe.getException() != null) {
+ e = sxe.getException();
+ }
+ e.printStackTrace();
+ System.exit(1);
+ } catch (ParserConfigurationException pce) {
+ pce.printStackTrace();
+ } catch (FileNotFoundException fnfe) {
+ System.err.println(
+ "warning: state file not found [" + filename + "]");
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ return;
}
- return;
- }
}
import java.util.Date;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-public class
-XMLHelper
-{
- static void
- dump_document (Document document)
- {
- dump_element(document.getDocumentElement(), 0);
- }
-
- static void
- dump_element (Element element, int indent)
- {
- NodeList nl = element.getChildNodes();
-
- System.out.println ("<" + element.getTagName() + ">");
- dump_nodelist(nl, indent + 1);
- System.out.println("</" + element.getTagName() + ">");
- }
-
- static void
- dump_nodelist (NodeList nl, int indent)
- {
- for (int loop = 0; loop < nl.getLength(); loop++)
- {
- Node node = nl.item(loop);
- switch (node.getNodeType())
- {
- case Node.ELEMENT_NODE :
- {
- dump_element((Element)node, indent);
- break;
- }
- case Node.TEXT_NODE :
- {
- System.out.println("TEXT: " + node.getNodeValue());
- break;
- }
- default :
- {
- System.out.println("NODE: " + node.getNodeType());
- }
- }
- }
- }
-
- static Node
- get_subnode (String name, Node node)
- {
- if (node.getNodeType() != Node.ELEMENT_NODE)
- {
- System.err.println("Error: Search node not of element type");
- return null;
+/**
+ * XMLHelper contains helper methods used to parse the XML state files.
+ */
+class XMLHelper {
+ /**
+ * Find a subnode with the specified name.
+ * @param name Name to look for.
+ * @param node Node from which to start search.
+ * @return The first subnode found, or null if none.
+ */
+ private static Node getSubNode(String name, Node node) {
+ if (node.getNodeType() != Node.ELEMENT_NODE) {
+ System.err.println("Error: Search node not of element type");
+ return null;
+ }
+
+ if (!node.hasChildNodes()) {
+ return null;
+ }
+
+ NodeList list = node.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node subnode = list.item(i);
+ if (subnode.getNodeType() == Node.ELEMENT_NODE) {
+ if (subnode.getNodeName() == name) {
+ return subnode;
+ }
+ }
+ }
+ return null;
}
- if (!node.hasChildNodes()) return null;
-
- NodeList list = node.getChildNodes();
- for (int i=0; i < list.getLength(); i++)
- {
- Node subnode = list.item(i);
- if (subnode.getNodeType() == Node.ELEMENT_NODE)
- {
- if (subnode.getNodeName() == name) return subnode;
- }
- }
- return null;
- }
-
- static String
- get_text (Node node)
- {
- StringBuffer result = new StringBuffer();
- if (node==null || !node.hasChildNodes()) return "";
-
- NodeList list = node.getChildNodes();
- for (int i=0; i < list.getLength(); i++)
- {
- Node subnode = list.item(i);
- if (subnode.getNodeType() == Node.TEXT_NODE)
- {
- result.append(subnode.getNodeValue());
- }
- }
- return result.toString();
- }
-
- static void
- parse (PartitionManager pm, VirtualDiskManager vdm, Document document)
- {
- if (document == null) return;
-
- /* parse partitions */
- parse_partitions(pm, document.getElementsByTagName("partition"));
-
- /* parse virtual disks */
- NodeList list = document.getElementsByTagName("virtual_disk");
- for (int i = 0; i < list.getLength(); i++)
- {
- Node subnode = list.item(i);
- String parent = subnode.getParentNode().getNodeName();
- VirtualDisk vd = parse_virtual_disk(subnode);
-
- if (parent.equals("free"))
- {
- vdm.add_free(vd);
- }
- else if (parent.equals("virtual_disks"))
- {
- vdm.add_virtual_disk(vd);
- }
- else
- {
- System.out.println ("XML parse error: unknown parent for virtual_disk "
- + "[" + parent + "]");
- }
+ /**
+ * Get all the text of a given node.
+ * @param node The node to examine.
+ * @return The node's text.
+ */
+ private static String getText(Node node) {
+ StringBuffer result = new StringBuffer();
+ if (node == null || !node.hasChildNodes()) {
+ return "";
+ }
+
+ NodeList list = node.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node subnode = list.item(i);
+ if (subnode.getNodeType() == Node.TEXT_NODE) {
+ result.append(subnode.getNodeValue());
+ }
+ }
+ return result.toString();
}
- /* parse virtual block devices */
- parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device"));
-
- return;
- }
-
- static VirtualDisk
- parse_virtual_disk(Node node)
- {
- VirtualDisk vd;
- Date date = new Date();
- NodeList list;
-
- long timestamp = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node)));
- if ( timestamp == 0 )
- date = null;
- else
- date.setTime( timestamp );
- vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)),
- date,
- XMLHelper.get_text(XMLHelper.get_subnode("key", node)));
-
- list = XMLHelper.get_subnode("extents", node).getChildNodes();
- for (int i = 0; i < list.getLength(); i++)
- {
- Node enode = list.item(i);
-
- if (enode.getNodeType() == Node.ELEMENT_NODE &&
- enode.getNodeName().equals("extent"))
- {
- Extent extent = new Extent();
-
- extent.disk = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("disk", enode)));
- extent.size = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("size", enode)));
- extent.offset = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("offset", enode)));
- vd.add_extent(extent);
- }
+ /**
+ * Parse the given configuration document and configure the managers.
+ * @param pm PartitionManager instance to configure.
+ * @param vdm VirtualDomainManager instance to configure.
+ * @param document Document to parse.
+ */
+ static void parse(
+ PartitionManager pm,
+ VirtualDiskManager vdm,
+ Document document) {
+ if (document == null) {
+ return;
+ }
+
+ /* parse partitions */
+ parsePartitions(pm, document.getElementsByTagName("partition"));
+
+ /* parse virtual disks */
+ NodeList list = document.getElementsByTagName("virtual_disk");
+ for (int i = 0; i < list.getLength(); i++) {
+ Node subnode = list.item(i);
+ String parent = subnode.getParentNode().getNodeName();
+ VirtualDisk vd = parseVirtualDisk(subnode);
+
+ if (parent.equals("free")) {
+ vdm.setFreeDisk(vd);
+ } else if (parent.equals("virtual_disks")) {
+ vdm.insertVirtualDisk(vd);
+ } else {
+ System.out.println(
+ "XML parse error: unknown parent for virtual_disk "
+ + "["
+ + parent
+ + "]");
+ }
+ }
+
+ /* parse virtual block devices */
+ parseVirtualBlockDevices(
+ vdm,
+ document.getElementsByTagName("virtual_block_device"));
+
+ return;
}
- return vd;
- }
-
- static void
- parse_partitions (PartitionManager pm, NodeList nl)
- {
- Partition partition;
-
- for (int loop = 0; loop < nl.getLength(); loop++)
- {
- Node node = nl.item(loop);
-
- partition = new Partition();
- partition.major = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("major", node)));
- partition.minor = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("minor", node)));
- partition.blocks = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("blocks", node)));
- partition.start_sect = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("start_sect", node)));
- partition.nr_sects = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("nr_sects", node)));
- partition.name = XMLHelper.get_text(XMLHelper.get_subnode("name", node));
+ /**
+ * Parse a node representing a virtual disk.
+ * @param node The node to parse.
+ * @return The VirtualDisk this node represents.
+ */
+ private static VirtualDisk parseVirtualDisk(Node node) {
+ VirtualDisk vd;
+ Date date = new Date();
+ NodeList list;
+
+ long timestamp =
+ Long.parseLong(
+ XMLHelper.getText(XMLHelper.getSubNode("expiry", node)));
+ if (timestamp == 0) {
+ date = null;
+ } else {
+ date.setTime(timestamp);
+ }
+ vd =
+ new VirtualDisk(
+ XMLHelper.getText(XMLHelper.getSubNode("name", node)),
+ date,
+ XMLHelper.getText(XMLHelper.getSubNode("key", node)));
+
+ list = XMLHelper.getSubNode("extents", node).getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node enode = list.item(i);
+
+ if (enode.getNodeType() == Node.ELEMENT_NODE
+ && enode.getNodeName().equals("extent")) {
+ Extent extent =
+ new Extent(
+ Integer.parseInt(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("disk", enode))),
+ Long.parseLong(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("size", enode))),
+ Long.parseLong(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("offset", enode))));
+ vd.addExtent(extent);
+ }
+ }
+
+ return vd;
+ }
- pm.add_xeno_partition(partition);
+ /**
+ * Parse a list of partition nodes.
+ * @param pm The partition manager to configure.
+ * @param nl The list of partition nodes.
+ */
+ private static void parsePartitions(PartitionManager pm, NodeList nl) {
+ Partition partition;
+
+ for (int loop = 0; loop < nl.getLength(); loop++) {
+ Node node = nl.item(loop);
+
+ partition =
+ new Partition(
+ Integer.parseInt(
+ XMLHelper.getText(XMLHelper.getSubNode("major", node))),
+ Integer.parseInt(
+ XMLHelper.getText(XMLHelper.getSubNode("minor", node))),
+ Integer.parseInt(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("blocks", node))),
+ Integer.parseInt(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("start_sect", node))),
+ Integer.parseInt(
+ XMLHelper.getText(
+ XMLHelper.getSubNode("nr_sects", node))),
+ XMLHelper.getText(XMLHelper.getSubNode("name", node)),
+ true);
+
+ pm.addXenoPartition(partition);
+ }
}
- }
-
- static void
- parse_virtual_block_devices (VirtualDiskManager vdm, NodeList nl)
- {
- for (int loop = 0; loop < nl.getLength(); loop++)
- {
- Node node = nl.item(loop);
-
- vdm.create_virtual_block_device(XMLHelper.get_text(XMLHelper.get_subnode("key", node)),
- Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("domain", node))),
- Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))),
- XMLHelper.get_text(XMLHelper.get_subnode("mode", node)));
+
+ /**
+ * Parse a list of virtual block device nodes.
+ * @param vdm The VirtualDiskManager to configure.
+ * @param nl The node list.
+ */
+ private static void parseVirtualBlockDevices(
+ VirtualDiskManager vdm,
+ NodeList nl) {
+ for (int loop = 0; loop < nl.getLength(); loop++) {
+ Node node = nl.item(loop);
+ Mode mode;
+
+ if (XMLHelper
+ .getText(XMLHelper.getSubNode("mode", node))
+ .equals("rw")) {
+ mode = Mode.READ_WRITE;
+ } else {
+ mode = Mode.READ_ONLY;
+ }
+
+ vdm.createVirtualBlockDevice(
+ vdm.getVirtualDisk(
+ XMLHelper.getText(XMLHelper.getSubNode("key", node))),
+ Integer.parseInt(
+ XMLHelper.getText(XMLHelper.getSubNode("domain", node))),
+ Integer.parseInt(
+ XMLHelper.getText(XMLHelper.getSubNode("vbdnum", node))),
+ mode);
+ }
}
- }
}